/**
  ******************************************************************************
  * @file    fsm_sensor.c
  * @author  Hanif Rizal
  * @version V1.0.0
  * @date    03-Maret-2013
  * @brief   Implementasi FSM Smart Transducer
  *              
  *  @verbatim
  *  
  *          ===================================================================
  *                                 How to use this driver
  *          ===================================================================              
  *   
  *  @endverbatim
  *    
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2013 Vibration Monitoring System TEAM</center></h2>
  ******************************************************************************
  */

#include "fsm_sensor.h"
#include "set_uart.h"
#include "set_adc.h"
#include "set_timer.h"

unsigned char fsm_state=STATE_ADDR;
unsigned char busy=0;

void fsm_sensor(unsigned char *state,unsigned char counter)
{
	static char ch=0; //untuk parsing data serial
	static int adctemp[4];//untuk temporary adc
	
	switch(*state)
	{
		case STATE_ADDR :
		//State untuk mengecek address sensor
		{
			if(counter > 0)//ada data serial
			{
				ch=myUART_Bufgetchar();
				if(ch==device_ADDR) //Adress cocok
				{
					*state=STATE_CMD;
					sprintf(kal,"ADDR Benar\r\n");
					myUART_Print(kal);
				}
				else
				{
					sprintf(kal,"ADDR Salah\r\n");
					myUART_Print(kal);
				}
			}
			break;
		}
		
		case STATE_CMD :
		//State untuk mengecek perintah master
		//CMD	01	Sample ACC Sb-X
		//CMD	02	Sample ACC Sb-Y
		//CMD	03	Sample ACC CH-Z
		//CMD	04	Sample 1024 Data 
		//CMD	05	Integrasi Data
		{
			if(counter>0)
			{
				ch=myUART_Bufgetchar();
				switch(ch)
				{
					case '1' :
					//CMD	01	Sample ACC Sb-X
					{
						busy=ch;
						*state=STATE_ACC_SB_X;
						//usart_putchar(USART_C0,'1');	
						break;
					}
					
					case '2' :
					//CMD	02	Sample ACC Sb-Y
					{
						busy=ch;
						*state=STATE_ACC_SB_Y;
						//usart_putchar(USART_C0,'2');
						break;
					}
					
					case '3' :
					//CMD	03	Sample ACC Sb-Z
					{
						busy=ch;
						*state=STATE_ACC_SB_Z;
						//usart_putchar(USART_C0,'3');
						break;
					}
					
					case '4' :
					//CMD	04	Sample 1024 Data
					{
						busy=ch;
						*state=STATE_ACC_S1024;
						//usart_putchar(USART_C0,'4');
						break;
					}
					
					case '5' :
					//CMD	05	Integrasi Data
					{
						busy=ch;
						*state=STATE_INTEGRAL;
						//usart_putchar(USART_C0,'5');
						break;
					}
					
					default:
					{
						busy=0;
						*state=STATE_ADDR;
						usart_putchar(USART_C0,'@');
					}
				
				}
			}
			break;
		}
		
		case STATE_ACC_SB_X :
		//Sample satu data dari SB-X kemudian kirim ke master
		{
			//sprintf(kal,"State ACC SB-X\r\n");
			//sprintf(kal,"Sb-X=%i\r\n",myADC_getdataCH0());
			//myUART_Print(kal);
			
			myADC_ClearBuff();
			myTimerStart();
			while(adc_counter0<1); //tunggu ada data adc
			adctemp[0]=myADC_Bufgetdata();
			sprintf(kal,"Sb-X=%i\r\n",adctemp[0]);
			myUART_Print(kal);
			myTimerStop();
			
			*state=STATE_ADDR;
			break;
		}
		
		case STATE_ACC_SB_Y :
		//Sample satu data dari SB-X kemudian kirim ke master
		{
			//sprintf(kal,"State ACC SB-Y\r\n");
			//sprintf(kal,"Sb-Y=%i\r\n",myADC_getdataCH1());
			//myUART_Print(kal);
			myADC_ClearBuff();
			myTimerStart();
			while(adc_counter0<2); //tunggu ada data adc
			adctemp[0]=myADC_Bufgetdata();
			adctemp[0]=myADC_Bufgetdata();
			myTimerStop();
			sprintf(kal,"Sb-Y=%i\r\n",adctemp[0]);
			myUART_Print(kal);
			*state=STATE_ADDR;
			break;
		}
		
		case STATE_ACC_SB_Z :
		//Sample satu data dari SB-X kemudian kirim ke master
		{
			//sprintf(kal,"State ACC SB-Z\r\n");
			//sprintf(kal,"Sb-Z=%i\r\n",myADC_getdataCH2());
			//myUART_Print(kal);
			
			myADC_ClearBuff();
			myTimerStart();
			while(adc_counter0<3); //tunggu ada data adc
			adctemp[0]=myADC_Bufgetdata();
			adctemp[0]=myADC_Bufgetdata();
			adctemp[0]=myADC_Bufgetdata();
			myTimerStop();
			sprintf(kal,"Sb-Z=%i\r\n",adctemp[0]);
			myUART_Print(kal);
			*state=STATE_ADDR;
			break;
		}
		
		case STATE_ACC_S1024 :
		//Sample satu data dari SB-X kemudian kirim ke master
		{
			//sprintf(kal,"State ACC S1024\r\n");
			//myUART_Print(kal);
			//myEventInit_ADC();
			//myTimerEventInit();
			myADC_ClearBuff();
			myTimerStart();
			while(adc_counter0<20); //Sample 20 Data
			myTimerStop();
			
			while(adc_counter0>0) //ada data adc
			{
				adctemp[0]=myADC_Bufgetdata();
				adctemp[1]=myADC_Bufgetdata();
				adctemp[2]=myADC_Bufgetdata();
				adctemp[3]=myADC_Bufgetdata();
					
				sprintf(kal,"%i\r\n%i\r\n%i\r\n%i\r\n",adctemp[0],adctemp[1],adctemp[2],adctemp[3]);
				myUART_Print(kal);
			}
			
			*state=STATE_ADDR;
			break;
		}
		
		case STATE_INTEGRAL :
		//Sample satu data dari SB-X kemudian kirim ke master
		{
			double velocity=0;	//Inisialisasi mula
			unsigned int temp=0;
			unsigned int xtemp=0;
			
			/*sprintf(kal,"State Integral\r\n");
			myUART_Print(kal);
			*state=STATE_ADDR;*/		
			
			deltah=32000000.0f/16384.0f;	//delta sampling
			deltah=1/deltah;
			sprintf(kal,"deltah=%f\r\n",deltah);		
			myUART_Print(kal);
			
			myADC_ClearBuff();
			myTimer1Init(40); //Set Timer 4 detik
									
			myTimer1Start(); //Start Timer
			myADC_StartSample();
			while(adc_counter0<4); //tunggu ada 1 sampling minimal
			myADC_StopSample();
			TCD1.CTRLA = TC_CLKSEL_OFF_gc;
			printf("Nilai Timer1=%i\r\n",TCD1.CNT);
			myTimer1Stop();
			
			myTimer1Start(); //Start Timer
			xtemp=myADC_Bufgetdata();
			xtemp+=myADC_Bufgetdata();
			xtemp+=myADC_Bufgetdata();
			xtemp+=myADC_Bufgetdata();
			xtemp=xtemp>>2; //Divide by 4
			velocity=((double)xtemp)/1000.0f; //Nilai Inisialisasi Kecepatan
			TCD1.CTRLA = TC_CLKSEL_OFF_gc;
			printf("Nilai Timer1=%i\r\n",TCD1.CNT);
			myTimer1Stop();
			
			printf("v Init=%f\r\n",velocity);
			
			myADC_ClearBuff();
			
			myTimer1Init(40); //Set Timer 4 detik
			myTimer1Start();
			myADC_StartSample();
			while(timD1CntFlag==0) //Flag hentikan integrasi
			{
				if(adc_counter0 >4) // Ada data ADC
				{
					temp=myADC_Bufgetdata(); //Sampling data
					temp+=myADC_Bufgetdata(); //Sampling data
					temp+=myADC_Bufgetdata(); //Sampling data
					temp+=myADC_Bufgetdata(); //Sampling data
					
					temp=temp>>2;	//Divide by 4
					temp=(temp+xtemp)>>1; //Divide by 2
					velocity = velocity + (((double)(temp))*deltah)/1000.0f;
					xtemp = temp;
				}
			}
			myADC_StopSample();
			myTimer1Stop(); //Stop Hitung
			
			myTimerEventInit();
			
			printf("v=%f\r\n",velocity);
			
			*state=STATE_ADDR;
			break;
		}
	}
}